#include "t_box_media.h"

T_Box_Control::T_Box_Control(T_Box_Core *a_core, T_Box_Thread *a_thread)
    : m_valid(false)
    , m_core(a_core)
    , m_thread(a_thread)
    , m_input(0)
    , m_format_ctx(0)
{
    m_valid = false;
    m_input = new T_Box_Input_Sequence(m_core->sequence());
    if(!m_input) return;
    Q_ASSERT(m_input->isValid());
    m_format_ctx = m_input->getAVFormatContext();
    if(!m_format_ctx) return;
    m_valid = true;
}

T_Box_Control::~T_Box_Control()
{
    if(m_format_ctx) av_close_input_file(m_format_ctx);
    if(m_input) delete m_input;
}

bool T_Box_Control::isValid()
{
    return m_valid;
}

AVFormatContext	*T_Box_Control::formatContext()
{
    return m_format_ctx;
}

T_Box_Thread *T_Box_Control::controlThread()
{
    return m_thread;
}

T_AV_Packet *T_Box_Control::readPacket()
{
    if(controlThread() && controlThread()->closing()) return NULL;
    AVPacket v_av_packet;
    if(::av_read_frame(m_format_ctx, &v_av_packet)<0)
    {
        return NULL;
    }
    T_AV_Packet *v_obj_packet = new T_AV_Packet(m_format_ctx, &v_av_packet);
    return v_obj_packet;
}

T_Box_Media *T_Box_Control::openMedia(AVMediaType a_media_type)
{
    Q_ASSERT(a_media_type==CODEC_TYPE_AUDIO||a_media_type==CODEC_TYPE_VIDEO);
    T_Box_Media *v_media = new T_Box_Media(this, a_media_type);
    if(!v_media) return NULL;
    if(v_media->isValid()) return v_media;
    delete v_media;
    return NULL;
}

T_Box_Media::T_Box_Media(T_Box_Control *a_control, AVMediaType a_media_type)
    : m_valid(false)
    , m_control(a_control)
    , m_media_type(a_media_type)
    , m_stream_index(-1)
    , m_stream(0)
    , m_codec_ctx(0)
{
    m_valid = false;
    if(m_media_type!=CODEC_TYPE_AUDIO && m_media_type!=CODEC_TYPE_VIDEO) return;
    QString v_media_type_str = m_media_type==CODEC_TYPE_AUDIO ? "audio" : "video";
    m_stream_index=-1;
    for(uint i=0; i<m_control->formatContext()->nb_streams; i++)
    {
        if(m_control->formatContext()->streams[i]->codec->codec_type==m_media_type)
        {
            m_stream_index=i;
            break;
        }
    }
    if(m_stream_index<0)
    {
        qDebug() << QString("No %1 stream.").arg(v_media_type_str);
        m_valid = false;
    }
    else
    {
        qDebug()<< QString("m_%1.stream.stream_index]").arg(v_media_type_str)
                << m_stream_index;
        m_valid = true;
        m_stream = m_control->formatContext()->streams[m_stream_index];
        m_codec_ctx=m_stream->codec;
        if(m_media_type==CODEC_TYPE_AUDIO)
        {
            if (m_codec_ctx->channels > 0)
            {
                m_codec_ctx->request_channels = FFMIN(2, m_codec_ctx->channels);
            }
            else
            {
                m_codec_ctx->request_channels = 2;
            }
        }
        m_codec=avcodec_find_decoder(m_codec_ctx->codec_id);
        if(!m_codec)
        {
            qDebug() << QString("Unsupported %1 codec.").arg(v_media_type_str);
            m_valid = false;
        }
        else
        {
            if(avcodec_open(m_codec_ctx, m_codec)<0)
            {
                qDebug() << QString("avcodec_open (%1) failed.").arg(v_media_type_str);
                m_valid = false;
            }
        }
    }
}

bool T_Box_Media::isValid()
{
    return m_valid;
}
